# 3分钟学会一个知识
from flask import Flask, request, jsonify
import json
#from test.test1 import generate_concept_explanation
from flask_cors import CORS
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_community.llms import OpenAI  # 或其他模型
from langchain_core import output_parsers
from langchain_core.output_parsers import StrOutputParser
import re
import os
import uuid
from langchain_core.runnables import RunnableSequence
app = Flask(__name__)
CORS(app)  # 允许跨域请求

os.environ["OPENAI_API_KEY"] = "sk-fhfopxxokpblqjbivoyhwhftlbjwrgeddccbytodqipkaqum"
base_url="https://api.siliconflow.cn/v1"
# 配置 SiliconFlow 的 OpenAI 兼容 API
llm = OpenAI(
    openai_api_base=base_url,
    api_key=os.environ.get("OPENAI_API_KEY"),
    model_name="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    temperature=0.2,
    top_p=0.1,
    max_tokens=1024
)

prompt_template =   """
角色：
创意解释专家

简介：
擅长用生动形象的生活化比喻解释复杂概念，能够根据不同受众的理解水平调整解释方式。

技能：
具备将抽象概念转化为具体比喻的能力，善于提炼核心要点，以及设计相关的测试题目。

规则：
1. 比喻必须简洁明了，不超过两句话。
2. 核心要点要用 emoji 图标辅助说明。
3. 选择题要围绕比喻和核心要点设计，具有针对性。
4. 输出格式严格为 json 对象，不使用 markdown 格式。

让我们慢慢地、一步一步地解决这个问题，以确保我们得到正确的答案。
工作流程的每个步骤都需要详细清晰的输出。
每个步骤都需要基于前面的内容。

工作流程（输出中间步骤和中间执行结果）：
1. 分析 {concept} 的本质特征。
2. 根据 {difficulty} 理解水平构思恰当的生活化比喻。
3. 提取关于该比喻的 3 个核心要点，并配上 emoji 图标。
4. 基于比喻和核心要点设计 1 道选择题。
5. 将以上内容整合成一个 json 
输出格式：
{{
    "name": "{concept}",
    "emoji": "{concept}的 emoji",
    "difficulty": 1-5之间数字,
    "analogy": "比喻内容...",
    "keyPoints": ["要点 1", "要点 2", "要点 3"],
    "quiz": [{{
        "question": "问题文本",
        "options": [
            {{"text": "选项 1", "correct": true/false}},
            {{"text": "选项 2", "correct": true/false}}
        ]
    }}]
}}
"""

# 提示词工程
ANALOGY_PROMPT = PromptTemplate(
    input_variables=["concept", "difficulty"],
    template= prompt_template
)
str_output_parser = StrOutputParser()   
def generate_concept_explanation(concept, difficulty):
    
    chain = LLMChain(
        llm=llm,
        prompt=ANALOGY_PROMPT,
        output_key="result"
    )
    
    response = chain.run({
        "concept": concept,
        "difficulty": difficulty
    })

    print(response,flush=True)  # 打印LLM返回的内容 (optiona)
    print("*************",response,flush=True)  # 打印LLM返回的内容 (optiona)
    if response.find("```json") > -1 and response.find("```") > -1:
        response = response.strip()[response.find("```json")+7:response.rfind("```") +0]
    
    response = response.replace("</think>", "").strip()
    print("*************",response,flush=True)  # 打印LLM返回的内容 (optiona)

    #LLM返回的内容 (optiona)
    try:
        # 尝试解析为JSON对象
        result = json.loads(response)
        print("----------------------------------------------")  # 打印解析后的JSON对象 (optional)
        print(result,flush=True)  # 打印解析后的JSON对象 (optional)
        result["id"] = uuid.uuid4()
        return result
    except json.JSONDecodeError as e:
        print(f"JSON解析失败，错误信息: {e}")  # 打印详细错误信息
        print(f"尝试解析的JSON字符串: {response}")  # 再次打印待解析的字符串
        # 如果解析失败，尝试使用正则表达式提取JSON内容
        return {} 


def explain_concept():
    data = request.json
    concept = data.get('concept')
    difficulty = data.get('difficulty', 'medium')
    
    # 调用LangChain处理
    result = generate_concept_explanation(concept, difficulty)
    
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='127.0.0.1',debug=True, port=5001)